package cn.zooz.admin.config.shiro.session;

import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.SessionKey;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.apache.shiro.web.session.mgt.WebSessionKey;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;

/**
 * Created by Bradish7Y on 2017/9/12.
 * custom WebSessionManager extends DefaultWebSessionManager
 * 防止RedisSessionDao.doReadSession多次被调用，保证多次请求只会有一次读redis缓存
 * 参考：https://github.com/alexxiyang/shiro-redis/pull/3  user:Twony
 */
@Slf4j
public class ZoozWebSessionManager extends DefaultWebSessionManager {

    @Override
    protected Session retrieveSession(SessionKey sessionKey) throws UnknownSessionException {
        Serializable sessionId = getSessionId(sessionKey);
        if (sessionId == null) {
            log.debug("Unable to resolve session ID from SessionKey [{}].  Returning null to indicate a " +
                    "session could not be found.", sessionKey);
            return null;
        }

        ServletRequest request = null;
        if (sessionKey instanceof WebSessionKey) {
            request = ((WebSessionKey) sessionKey).getServletRequest();
        }

        if (request != null) {
            Object obj = request.getAttribute(sessionId.toString());
            if (obj != null) {
                return (Session) obj;
            }
        }

        Session s = retrieveSessionFromDataSource(sessionId);
        if (s == null) {
            //session ID was provided, meaning one is expected to be found, but we couldn't find one:
            String msg = "Could not find session with ID [" + sessionId + "]";
            throw new UnknownSessionException(msg);
        }

        if (request != null) {
            request.setAttribute(sessionId.toString(), s);
        }

        return s;
    }

    @Override
    protected void delete(Session session) {
        super.delete(session);
        /**
         * 退出后从request中删除该session
         */
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        request.removeAttribute(session.getId().toString());
    }
}
